#include <IOExpander.h>

IOExpander IOexp;

uint8_t *chipOut=IOexp.IO_CHIPB;
uint8_t puertoOut=IOexp.IO_PORTB;

uint8_t *chipIn=IOexp.IO_CHIPA;
uint8_t puertoIn=IOexp.IO_PORTA;

volatile uint8_t state=0;
volatile uint8_t stateAnt=0;

volatile uint8_t data;
int latencia=200;

  
void setup(){
  IOexp.begin(7,0);
  IOexp.portMode(chipOut, puertoOut, IOexp.ioOUTPUT);  
  IOexp.portMode(chipIn, puertoIn, IOexp.ioINPUT);  
  //Se configura la interrupciÃ³n en el pin 2 (interrupciÃ³n 0) para que si cambia el puerto A del Chip 1 lance la interrupciÃ³n
  attachInterrupt(0, lectura, RISING);
  IOexp.digitalConfigureInterruptsPort(chipIn, puertoIn, 0x1F);  
}

void lectura()
{
  //if(!interruption){
   // interruption=true;
   stateAnt=state;
    state=5;
  //}
}

void loop(){
  int i=0;
  int j=0;
  int st2=0;
  int st3=0;
  while(true){
    if(i>=8){
      i=0;
      st3++;
    }
    j++;
    if(j>=latencia){
      j=0;
      st2++;
    }
    switch(state){
      case 0:
        //delay(2);
        switch(st2){
          case 0:
            IOexp.digitalWrite(chipOut, puertoOut, i, 1);
            break;
          case 1:
            IOexp.digitalWrite(chipOut, puertoOut, i, 0);
            break;
          default:
            i++;
            st2=0;
            break;
        }
      break;
      case 1:
        switch(st2){
          case 0:
            IOexp.digitalWrite(chipOut, puertoOut, 7-i, HIGH);
            break;
          case 1:
            IOexp.digitalWrite(chipOut, puertoOut, 7-i, LOW);
            break;
          default:
            i++;
            st2=0;
            break;
        }
     break;
     case 2:
        switch(st3){
          case 0:
            switch(st2){
              case 0:
                IOexp.digitalWrite(chipOut, puertoOut, i, 1);
                break;
              case 1:
                IOexp.digitalWrite(chipOut, puertoOut, i, 0);
                break;
              default:
                st2=0;
                i++;
                break;
            }
            break;
          case 1:
            switch(st2){
              case 0:
                IOexp.digitalWrite(chipOut, puertoOut, 7-i, 1);
                break;
              case 1:
                IOexp.digitalWrite(chipOut, puertoOut, 7-i, 0);
                break;
              default:
                st2=0;
                i++;
                break;
            }
            break;
          default:
            st3=0;
            break;
        }
    break;
    case 3:
      switch(st2){
          case 0:
          case 1:
            IOexp.digitalWritePort(chipOut, puertoOut, 255);
            break;
          case 2:
          case 3:
            IOexp.digitalWritePort(chipOut, puertoOut, 0b00000000);
            break;
          case 4:
          case 5:
          IOexp.digitalWritePort(chipOut, puertoOut, 0xff);
            break;
          case 6:
          case 7:
          case 8:
          case 9:
          case 10:
          case 11:
          IOexp.digitalWritePort(chipOut, puertoOut, 0x00);
            break;
          default:
            st2=0;
            break;
        } 
      break;
    case 4:
      switch(st2){
          case 0:
            IOexp.digitalWritePort(chipOut, puertoOut, 255);
            break;
          case 1:
            IOexp.digitalWritePort(chipOut, puertoOut, 0b00000000);
            break;
          case 2:
            IOexp.digitalWritePort(chipOut, puertoOut, 255);
            break;
          case 3:
            IOexp.digitalWritePort(chipOut, puertoOut, 0b00000000);
            break;
          case 4:
          case 5:
          IOexp.digitalWritePort(chipOut, puertoOut, 0xff);
            break;
          case 6:
          case 7:
          case 8:
          case 9:
          IOexp.digitalWritePort(chipOut, puertoOut, 0x00);
            break;
          default:
            st2=0;
            break;
        } 
      break;
      case 5:    
        data=IOexp.digitalReadPortChipA(puertoIn);
        if(data==0){
          state=stateAnt;
        }else{
          if(data>0){
            if(data<2){
              state=0;
            }else{
              if(data<4){
                state=1;
              }else{
                if(data<8){
                  state=2;
                }else{
                  if(data<16){
                    state=3;
                  }else{
                    if(data<32){
                      state=4;
                    }
                  }
                }
              }
            }
          }
          st2=0;
        }
        break;
    }
  }
}

